package staff.io;

import static staff.util.StringUtils.TXT_PARAM_DELIMITER;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.Reader;
import java.util.Scanner;

import staff.logic.Employee;

/**
 * Class for reading employes from text file. Each line in file must holds param
 * in order according to Employe.FieldsTags definition
 */
public class TxtEmployeLoader implements EmployeLoader {
    private Employee next = null;
    private Scanner scanner;

    public TxtEmployeLoader(String fileName) throws FileNotFoundException {
        Reader reader = new BufferedReader(new FileReader(fileName));
        scanner = new Scanner(reader);
        next = getNext();
    }

    /** Has next employe to load */
    public boolean hasNext() {
        return (next != null);
    }

    /** Load next employe */
    public Employee loadNext() {
        if (hasNext()) {
            Employee result = next;
            next = getNext();
            return result;
        } else {
            throw new IllegalStateException("There is no more employe to load.");
        }
    }

    /** Close underlying stream */
    public void close() {
        scanner.close();
    }

    /** Search next employe in text file */
    private Employee getNext() {
        Employee nextEmploye = null;
        if (scanner.hasNextLine()) {
            // get employe from string
            nextEmploye = getEmployeFromString(scanner.nextLine());
            // if parsing not succefull then try again with next line
            while (nextEmploye == null && scanner.hasNextLine()) {
                nextEmploye = getEmployeFromString(scanner.nextLine());
            }
        }
        return nextEmploye;
    }

    /** Get employe from string */
    private Employee getEmployeFromString(String line) {
        Employee employe = null;
        String employeString = line.trim();
        if (!employeString.isEmpty()) {
            Scanner paramScanner = new Scanner(employeString);
            paramScanner.useDelimiter(TXT_PARAM_DELIMITER);
            employe = new Employee();
            // process all employe fields. Values in line must be in
            // EmployeFieldTag order
            for (Employee.FieldTag tag : Employee.FieldTag.values()) {
                // if exists value then set next param
                if (paramScanner.hasNext()) {
                    String value = paramScanner.next().trim();
                    if (!value.isEmpty()) {
                        employe.setParamByName(tag.toString(), value);
                    }
                }
            }
        }
        return employe;
    }

}
